package tcp

import (
	"bufio"
	"bytes"
	"encoding/binary"
	"errors"
	"log"
	"net"
)

// NewConn 新建Tcp连接
func NewConn(remoteAddr string) (net.Conn, error) {
	conn, err := net.Dial("tcp", remoteAddr)
	if err != nil {
		log.Printf("新建连接错误，err: %v", err)
		return nil, err
	}

	return conn, nil
}

// Encode 编码消息头
func encode(message []byte) ([]byte, error) {
	lenMsg := int32(len(message))

	head := new(bytes.Buffer)
	err := binary.Write(head, binary.LittleEndian, lenMsg)
	if err != nil {
		return nil, err
	}

	err = binary.Write(head, binary.LittleEndian, message)
	if err != nil {
		return nil, err
	}
	return head.Bytes(), nil
}

// PreviewRequest 预检请求
func previewRequest(conn net.Conn, message []byte) error {
	reader := bufio.NewReader(conn)
	head, err := encode(message)
	if err != nil {
		log.Println(err)
		return err
	}

	conn.Write(head)

	res := make([]byte, 2)
	reader.Read(res)

	if string(res) != "OK" {
		err := errors.New("预检请求失败！")
		return err
	}

	return nil
}

// Transfer 传输流
func Transfer(pool *Pool, handler Handler, resource []byte) {
	conn, err := pool.GetConn()
	if err != nil {
		for {
			conn, _ = pool.GetConn()
			if conn != nil {
				break
			}
		}
	}
	defer pool.Release(conn)

	err = previewRequest(conn, resource)
	if err != nil {
		log.Println(err)
		return
	}

	_, err = handler.Handle(conn, resource)
	if err != nil {
		log.Println(err)
	}
	return
}
